/*
 * Copyright (c) 2022-2024 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, Hardware
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "gtest/gtest.h"

#include "drawing_brush.h"
#include "drawing_color.h"
#include "drawing_error_code.h"
#include "drawing_filter.h"
#include "drawing_mask_filter.h"
#include "drawing_rect.h"
#include "drawing_shadow_layer.h"
#include "drawing_color_filter.h"
#include "effect/color_filter.h"
#include "effect/filter.h"

using namespace testing;
using namespace testing::ext;

namespace Keels {
namespace Rosen {
namespace Drawing {
class NativeDrawingBrushTest : public testing::Test {
public:
    static void SetUpTestCase();
    static void TearDownTestCase();
    void SetUp() override;
    void TearDown() override;
};

void NativeDrawingBrushTest::SetUpTestCase() {}
void NativeDrawingBrushTest::TearDownTestCase() {}
void NativeDrawingBrushTest::SetUp() {}
void NativeDrawingBrushTest::TearDown() {}

static Filter* CastToFilter(Keels_Drawing_Filter* cFilter)
{
    return reinterpret_cast<Filter*>(cFilter);
}

/*
 * @tc.name: NativeDrawingBrushTest_brushCreate001
 * @tc.desc: test for create brush and destroy brush.
 * @tc.type: FUNC
 * @tc.require: AR000GTO5R
 */
HWTEST_F(NativeDrawingBrushTest, NativeDrawingBrushTest_brushCreate001, TestSize.Level1)
{
    Keels_Drawing_Brush* brush = Keels_Drawing_BrushCreate();
    EXPECT_EQ(brush == nullptr, false);
    Keels_Drawing_BrushDestroy(brush);
}

/*
 * @tc.name: NativeDrawingBrushTest_brushSetColor002
 * @tc.desc: test for the set methods of brush.
 * @tc.type: FUNC
 * @tc.require: AR000GTO5R
 */
HWTEST_F(NativeDrawingBrushTest, NativeDrawingBrushTest_brushSetColor002, TestSize.Level1)
{
    Keels_Drawing_Brush* brush1 = Keels_Drawing_BrushCreate();
    Keels_Drawing_BrushSetAntiAlias(brush1, false);
    EXPECT_EQ(Keels_Drawing_BrushIsAntiAlias(brush1), false);
    Keels_Drawing_BrushSetAntiAlias(nullptr, false);
    EXPECT_EQ(Keels_Drawing_ErrorCodeGet(), KEELS_DRAWING_ERROR_INVALID_PARAMETER);
    EXPECT_EQ(Keels_Drawing_BrushIsAntiAlias(nullptr), false);
    EXPECT_EQ(Keels_Drawing_ErrorCodeGet(), KEELS_DRAWING_ERROR_INVALID_PARAMETER);
    Keels_Drawing_BrushSetColor(brush1, Keels_Drawing_ColorSetArgb(0xFF, 0xFF, 0x00, 0x00));
    EXPECT_EQ(Keels_Drawing_BrushGetColor(brush1), 0xFFFF0000);
    Keels_Drawing_BrushSetColor(nullptr, Keels_Drawing_ColorSetArgb(0xFF, 0xFF, 0x00, 0x00));
    EXPECT_EQ(Keels_Drawing_ErrorCodeGet(), KEELS_DRAWING_ERROR_INVALID_PARAMETER);
    EXPECT_EQ(Keels_Drawing_BrushGetColor(nullptr), 0);
    EXPECT_EQ(Keels_Drawing_ErrorCodeGet(), KEELS_DRAWING_ERROR_INVALID_PARAMETER);
    constexpr uint8_t alpha = 128;
    Keels_Drawing_BrushSetAlpha(brush1, alpha);
    EXPECT_EQ(Keels_Drawing_BrushGetAlpha(brush1), alpha);
    Keels_Drawing_BrushSetAlpha(nullptr, alpha);
    EXPECT_EQ(Keels_Drawing_ErrorCodeGet(), KEELS_DRAWING_ERROR_INVALID_PARAMETER);
    EXPECT_EQ(Keels_Drawing_BrushGetAlpha(nullptr), 0);
    EXPECT_EQ(Keels_Drawing_ErrorCodeGet(), KEELS_DRAWING_ERROR_INVALID_PARAMETER);
}

/*
 * @tc.name: NativeDrawingBrushTest_brushSetBlendMode003
 * @tc.desc: test for SetBlendMode.
 * @tc.type: FUNC
 * @tc.require: AR000GTO5R
 */
HWTEST_F(NativeDrawingBrushTest, NativeDrawingBrushTest_brushSetBlendMode003, TestSize.Level1)
{
    Keels_Drawing_BrushSetBlendMode(nullptr, Keels_Drawing_BlendMode::KEELS_BLEND_MODE_CLEAR);
    EXPECT_EQ(Keels_Drawing_ErrorCodeGet(), KEELS_DRAWING_ERROR_INVALID_PARAMETER);
    Keels_Drawing_Brush* brush = Keels_Drawing_BrushCreate();
    EXPECT_NE(brush, nullptr);
    Keels_Drawing_BrushSetBlendMode(brush, Keels_Drawing_BlendMode::KEELS_BLEND_MODE_CLEAR);
}

/*
 * @tc.name: NativeDrawingBrushTest_brushReset004
 * @tc.desc: test for the reset methods of brush.
 * @tc.type: FUNC
 * @tc.require: AR000GTO5R
 */
HWTEST_F(NativeDrawingBrushTest, NativeDrawingBrushTest_brushReset004, TestSize.Level1)
{
    Keels_Drawing_Brush* brush1 = Keels_Drawing_BrushCreate();
    Keels_Drawing_BrushSetAntiAlias(brush1, true);
    Keels_Drawing_BrushSetColor(brush1, Keels_Drawing_ColorSetArgb(0x00, 0xFF, 0x00, 0xFF));
    constexpr uint8_t alpha = 128;
    Keels_Drawing_BrushSetAlpha(brush1, alpha);

    Keels_Drawing_BrushReset(brush1);
    EXPECT_EQ(Keels_Drawing_BrushIsAntiAlias(brush1), false);
    EXPECT_EQ(Keels_Drawing_BrushGetColor(brush1), 0xFF000000);
    EXPECT_EQ(Keels_Drawing_BrushGetAlpha(brush1), 0xFF);
    Keels_Drawing_BrushReset(nullptr);
    EXPECT_EQ(Keels_Drawing_ErrorCodeGet(), KEELS_DRAWING_ERROR_INVALID_PARAMETER);

    Keels_Drawing_BrushDestroy(brush1);
}

/*
 * @tc.name: NativeDrawingBrushTest_brushGetFilter005
 * @tc.desc: gets the filter from a brush.
 * @tc.type: FUNC
 * @tc.require: AR000GTO5R
 */
HWTEST_F(NativeDrawingBrushTest, NativeDrawingBrushTest_brushGetFilter005, TestSize.Level1)
{
    Keels_Drawing_Brush* brush = Keels_Drawing_BrushCreate();
    EXPECT_NE(brush, nullptr);
    Keels_Drawing_Filter* cFilter_ = Keels_Drawing_FilterCreate();
    EXPECT_NE(cFilter_, nullptr);
    Keels_Drawing_Filter* tmpFilter_ = Keels_Drawing_FilterCreate();
    EXPECT_NE(tmpFilter_, nullptr);

    Keels_Drawing_ColorFilter* colorFilterTmp = Keels_Drawing_ColorFilterCreateLinearToSrgbGamma();

    Keels_Drawing_FilterSetColorFilter(cFilter_, nullptr);
    Keels_Drawing_FilterGetColorFilter(cFilter_, colorFilterTmp);
    EXPECT_EQ((reinterpret_cast<ColorFilter*>(colorFilterTmp))->GetType(), ColorFilter::FilterType::NO_TYPE);

    Keels_Drawing_ColorFilter* cColorFilter_ = Keels_Drawing_ColorFilterCreateBlendMode(0xFF0000FF, KEELS_BLEND_MODE_COLOR);
    Keels_Drawing_FilterSetColorFilter(cFilter_, cColorFilter_);
    Keels_Drawing_BrushSetFilter(brush, cFilter_);
    Keels_Drawing_BrushGetFilter(brush, tmpFilter_);

    EXPECT_NE(CastToFilter(tmpFilter_)->GetColorFilter(), nullptr);
    EXPECT_EQ(CastToFilter(tmpFilter_)->GetColorFilter()->GetType(), ColorFilter::FilterType::BLEND_MODE);

    Keels_Drawing_BrushSetFilter(nullptr, cFilter_);
    EXPECT_EQ(Keels_Drawing_ErrorCodeGet(), KEELS_DRAWING_ERROR_INVALID_PARAMETER);
    Keels_Drawing_BrushGetFilter(nullptr, tmpFilter_);
    EXPECT_EQ(Keels_Drawing_ErrorCodeGet(), KEELS_DRAWING_ERROR_INVALID_PARAMETER);
    Keels_Drawing_BrushGetFilter(brush, nullptr);
    EXPECT_EQ(Keels_Drawing_ErrorCodeGet(), KEELS_DRAWING_ERROR_INVALID_PARAMETER);

    Keels_Drawing_FilterDestroy(cFilter_);
    Keels_Drawing_FilterDestroy(tmpFilter_);
    Keels_Drawing_ColorFilterDestroy(cColorFilter_);
    Keels_Drawing_ColorFilterDestroy(colorFilterTmp);
    Keels_Drawing_BrushDestroy(brush);
}

/*
 * @tc.name: NativeDrawingBrushTest_brushSetShadowLayer006
 * @tc.desc: test for the set methods of brush.
 * @tc.type: FUNC
 * @tc.require: AR000GTO5R
 */
HWTEST_F(NativeDrawingBrushTest, NativeDrawingBrushTest_brushSetShadowLayer006, TestSize.Level1)
{
    // blurRadius:-3.f, offset:(-3.f, 3.f), shadowColor:green
    Keels_Drawing_ShadowLayer* shadow = Keels_Drawing_ShadowLayerCreate(-3.f, -3.f, 3.f, 0xFF00FF00);
    EXPECT_EQ(shadow, nullptr);
    Keels_Drawing_ShadowLayerDestroy(nullptr);
    // blurRadius:3.f, offset:(-3.f, 3.f), shadowColor:green
    Keels_Drawing_ShadowLayer* shadowLayer = Keels_Drawing_ShadowLayerCreate(3.f, -3.f, 3.f, 0xFF00FF00);
    EXPECT_NE(shadowLayer, nullptr);
    Keels_Drawing_Brush* brush = Keels_Drawing_BrushCreate();
    EXPECT_NE(brush, nullptr);
    Keels_Drawing_BrushSetShadowLayer(nullptr, shadowLayer);
    EXPECT_EQ(Keels_Drawing_ErrorCodeGet(), KEELS_DRAWING_ERROR_INVALID_PARAMETER);
    Keels_Drawing_BrushSetShadowLayer(brush, nullptr);
    Keels_Drawing_BrushSetShadowLayer(brush, shadowLayer);
    Keels_Drawing_ShadowLayerDestroy(shadowLayer);
    Keels_Drawing_BrushDestroy(brush);
}

/*
 @tc.name: NativeDrawingBrushTest_brushCopy007
 * @tc.desc: test for creates an copy object.
 * @tc.type: FUNC
 * @tc.require: AR000GTO5R
 */
HWTEST_F(NativeDrawingBrushTest, NativeDrawingBrushTest_brushCopy007, TestSize.Level1)
{
    Keels_Drawing_Brush* brush = Keels_Drawing_BrushCreate();
    EXPECT_EQ(brush == nullptr, false);
    Keels_Drawing_Brush* brush_copy = Keels_Drawing_BrushCopy(brush);
    EXPECT_EQ(brush_copy == nullptr, false);
    Keels_Drawing_BrushDestroy(brush);
    Keels_Drawing_BrushDestroy(brush_copy);
}
} // namespace Drawing
} // namespace Rosen
} // namespace Keels